Gamepad API â veb-oâyinlarda kontroller kiritishini boshqarish uchun kuchli vositani oârganing. Kontrollerni aniqlash, tugma va oâqlarni xaritalash hamda qiziqarli brauzer oâyinlarini yaratishni oârganing.
Gamepad API: Brauzer O'yinlarida Kiritishni Boshqarish va Kontrollerni Boshqarish
Gamepad API brauzerda boy va qiziqarli o'yin tajribalarini yaratish uchun muhim texnologiyadir. U veb-dasturchilarga turli geympadlar va kontrollerlardan kiritish ma'lumotlarini olish va boshqarishning standartlashtirilgan usulini taqdim etadi. Ushbu postda Gamepad API'ning nozikliklari, uning xususiyatlari, amaliy qo'llanilishi va global auditoriya uchun sezgir va qiziqarli veb-asosidagi o'yinlarni yaratish bo'yicha eng yaxshi amaliyotlar ko'rib chiqiladi. Biz kontrollerni aniqlash, tugma va o'qlarni xaritalashni yoritamiz va sizga boshlashga yordam beradigan kod misollarini taqdim etamiz.
Gamepad API'ni Tushunish
Gamepad API veb-ilovalariga geympadlar va boshqa kiritish qurilmalari bilan o'zaro ishlash imkonini beruvchi JavaScript API'dir. U aniq kontroller uskunasidan qat'i nazar, kiritish ma'lumotlarini olish uchun izchil interfeysni taqdim etadi. Bu standartlashtirish dasturlashni soddalashtiradi, chunki dasturchilar har bir turdagi geympad uchun alohida kod yozishlari shart emas. API ulangan geympadlarni aniqlash, tugmachalarni bosish va o'q qiymatlarini olish hamda kontroller holatlarini boshqarish imkonini beradi.
Asosiy Tushunchalar:
- Gamepad Obyektlari: API har bir ulangan geympad uchun
Gamepadobyektini taqdim etadi. Ushbu obyekt geympad haqida, jumladan uning ID'si, tugmalari, o'qlari va ulanish holati haqida ma'lumotlarni o'z ichiga oladi. - Tugma Obyektlari: Geympaddagi har bir tugma
GamepadButtonobyekti bilan ifodalanadi. Ushbu obyektdapressed(mantiqiy, tugma hozir bosilganmi),value(tugma qanchalik bosilganligini ko'rsatuvchi 0 dan 1 gacha bo'lgan raqam) vatouched(mantiqiy, tugmaga tegib turilganmi) kabi xususiyatlar mavjud. - O'qlar: O'qlar geympaddagi stiklar yoki triggerlar kabi analog kiritishni ifodalaydi.
Gamepadobyektiningaxesxususiyati har bir o'qning joriy holatini ifodalovchi suzuvchi nuqtali raqamlar massividir. Qiymatlar odatda -1 dan 1 gacha bo'ladi. - Hodisalar: Gamepad API geympad bilan bog'liq o'zgarishlar haqida veb-ilovani xabardor qilish uchun hodisalardan foydalanadi. Eng muhim hodisa bu
gamepadconnectedbo'lib, geympad ulanganda ishga tushadi, vagamepaddisconnected, geympad uzilganda ishga tushadi.
Geympadlarni Aniqlash
Gamepad API'dan foydalanishning birinchi qadami ulangan geympadlarni aniqlashdir. Bu odatda gamepadconnected va gamepaddisconnected hodisalarini tinglash orqali amalga oshiriladi. Ushbu hodisalar window obyektida ishga tushadi.
window.addEventListener('gamepadconnected', (event) => {
const gamepad = event.gamepad;
console.log(`Gamepad connected: ${gamepad.id}`);
// Handle gamepad connection (e.g., store the gamepad object)
updateGamepads(); // Update the list of available gamepads
});
window.addEventListener('gamepaddisconnected', (event) => {
const gamepad = event.gamepad;
console.log(`Gamepad disconnected: ${gamepad.id}`);
// Handle gamepad disconnection (e.g., remove the gamepad object)
updateGamepads(); // Update the list of available gamepads
});
gamepadconnected hodisasi ulangan kontrollerni ifodalovchi Gamepad obyektini taqdim etadi. gamepaddisconnected hodisasi ham xuddi shunday obyektni taqdim etib, geympadni aniqlash va o'yin mantiqidan olib tashlash imkonini beradi. updateGamepads() (keyingi misolda ko'rsatilgan) kabi funksiya mavjud geympadlar ro'yxatini yangilash uchun juda muhimdir.
Geympadlarni To'g'ridan-to'g'ri Tekshirish
Siz shuningdek ulangan geympadlarni navigator.getGamepads() usuli yordamida to'g'ridan-to'g'ri tekshirishingiz mumkin. Bu usul Gamepad obyektlari massivini qaytaradi. Massivdagi har bir element ulangan geympadni yoki agar o'sha indeksda geympad ulanmagan bo'lsa, nullni ifodalaydi. Bu usul o'yinni ishga tushirish yoki ulangan kontrollerlarni tezda tekshirish uchun foydalidir.
function updateGamepads() {
const gamepads = navigator.getGamepads();
console.log(gamepads);
for (let i = 0; i < gamepads.length; i++) {
if (gamepads[i]) {
console.log(`Gamepad ${i}: ${gamepads[i].id}`);
}
}
}
updateGamepads(); // Initial check
Kiritishni O'qish: Tugmalar va O'qlar
Geympadni aniqlaganingizdan so'ng, uning kiritish ma'lumotlarini o'qishingiz mumkin. Gamepad API tugma holatlari va o'q qiymatlariga kirish uchun xususiyatlarni taqdim etadi. Bu jarayon odatda o'yinning asosiy yangilanish sikli ichida sodir bo'ladi, bu esa real vaqtda javob berish imkonini beradi.
Tugma Holatlarini O'qish
Har bir Gamepad obyekti buttons massiviga ega. Ushbu massivdagi har bir element GamepadButton obyektidir. pressed xususiyati tugmaning hozirda bosilganligini ko'rsatadi.
function updateInput() {
const gamepads = navigator.getGamepads();
if (!gamepads) return;
for (let i = 0; i < gamepads.length; i++) {
const gamepad = gamepads[i];
if (!gamepad) continue;
// Iterate through buttons
for (let j = 0; j < gamepad.buttons.length; j++) {
const button = gamepad.buttons[j];
if (button.pressed) {
console.log(`Button ${j} pressed on ${gamepad.id}`);
// Perform actions based on button presses
}
}
}
}
O'q Qiymatlarini O'qish
Gamepad obyektining axes xususiyati o'qlarning holatini ifodalovchi suzuvchi nuqtali raqamlar massividir. Bu qiymatlar odatda -1 dan 1 gacha bo'ladi.
function updateInput() {
const gamepads = navigator.getGamepads();
if (!gamepads) return;
for (let i = 0; i < gamepads.length; i++) {
const gamepad = gamepads[i];
if (!gamepad) continue;
// Access axis values (e.g., left stick X and Y)
const xAxis = gamepad.axes[0]; // Typically left stick X-axis
const yAxis = gamepad.axes[1]; // Typically left stick Y-axis
if (Math.abs(xAxis) > 0.1 || Math.abs(yAxis) > 0.1) {
console.log(`Left Stick: X: ${xAxis.toFixed(2)}, Y: ${yAxis.toFixed(2)}`);
// Use axis values for movement or control
}
}
}
O'yin Sikli
Geympad kiritishini yangilash mantiqi o'yiningizning asosiy sikli ichiga joylashtirilishi kerak. Bu sikl o'yin holatini yangilash, foydalanuvchi kiritishini boshqarish va o'yin sahnasini chizish uchun mas'uldir. Yangilanish siklining vaqti sezgirlik uchun juda muhim; odatda, siz requestAnimationFrame() dan foydalanasiz.
function gameLoop() {
updateInput(); // Handle gamepad input
// Update game state (e.g., character position)
// Render the game scene
requestAnimationFrame(gameLoop);
}
// Start the game loop
gameLoop();
Ushbu misolda, geympad kiritishini qayta ishlash uchun har bir kadr boshida updateInput() chaqiriladi. Boshqa funksiyalar umumiy foydalanuvchi tajribasi uchun muhim bo'lgan o'yin holati va renderlashni boshqaradi.
Kontroller Kiritishlarini Xaritalash
Turli geympadlarda tugmalarning joylashuvi har xil bo'lishi mumkin. Turli kontrollerlarda bir xil tajribani ta'minlash uchun jismoniy tugmalar va o'qlarni o'yiningizdagi mantiqiy harakatlarga xaritalashingiz kerak bo'ladi. Bu xaritalash jarayoni qaysi tugmalar va o'qlar muayyan o'yin funksiyalariga mos kelishini aniqlashni o'z ichiga oladi.
Misol: Harakat va Amallarni Xaritalash
Oddiy platformer o'yinini ko'rib chiqaylik. Siz quyidagilarni xaritalashingiz mumkin:
- Chap Stik/D-pad: Harakat (chapga, o'ngga, yuqoriga, pastga)
- A Tugmasi: Sakrash
- B Tugmasi: Harakat (masalan, otish)
const INPUT_MAPPINGS = {
// Assuming common controller layout
'A': {
button: 0, // Typically the 'A' button on many controllers
action: 'jump',
},
'B': {
button: 1,
action: 'shoot',
},
'leftStickX': {
axis: 0,
action: 'moveHorizontal',
},
'leftStickY': {
axis: 1,
action: 'moveVertical',
},
};
function handleGamepadInput(gamepad) {
if (!gamepad) return;
const buttons = gamepad.buttons;
const axes = gamepad.axes;
// Button Input
for (const buttonKey in INPUT_MAPPINGS) {
const mapping = INPUT_MAPPINGS[buttonKey];
if (mapping.button !== undefined && buttons[mapping.button].pressed) {
const action = mapping.action;
console.log(`Action triggered: ${action}`);
// Perform the action based on the button pressed
}
}
// Axis Input
if(INPUT_MAPPINGS.leftStickX) {
const xAxis = axes[INPUT_MAPPINGS.leftStickX.axis];
if (Math.abs(xAxis) > 0.2) {
//Handle horizontal movement, e.g., setting player.xVelocity
console.log("Horizontal Movement: " + xAxis)
}
}
if(INPUT_MAPPINGS.leftStickY) {
const yAxis = axes[INPUT_MAPPINGS.leftStickY.axis];
if (Math.abs(yAxis) > 0.2) {
//Handle vertical movement, e.g., setting player.yVelocity
console.log("Vertical Movement: " + yAxis)
}
}
}
function updateInput() {
const gamepads = navigator.getGamepads();
if (!gamepads) return;
for (let i = 0; i < gamepads.length; i++) {
const gamepad = gamepads[i];
if (gamepad) {
handleGamepadInput(gamepad);
}
}
}
Ushbu misol kontroller kiritishlarini (tugmalar va o'qlar) o'yinga xos harakatlarga aylantiruvchi xaritalash obyektini qanday aniqlashni ko'rsatadi. Bu yondashuv sizga turli kontroller tartiblariga osongina moslashish imkonini beradi va kodni o'qilishi oson va saqlanishi qulay qiladi. Keyin handleGamepadInput() funksiyasi ushbu harakatlarni qayta ishlaydi.
Bir Nechta Kontrollerni Boshqarish
Agar o'yiningiz ko'p o'yinchili rejimni qo'llab-quvvatlasa, siz bir nechta ulangan geympadlarni boshqarishingiz kerak bo'ladi. Gamepad API sizga mavjud geympadlar bo'ylab osongina iteratsiya qilish va har biridan alohida kiritish ma'lumotlarini olish imkonini beradi, bu avvalgi misollarda ko'rsatilgan. Ko'p o'yinchili funksionallikni amalga oshirayotganda, har bir o'yinchini qanday aniqlash va ularni ma'lum bir geympad bilan bog'lashni diqqat bilan ko'rib chiqing. Bu aniqlash ko'pincha navigator.getGamepads() massividagi geympad indeksidan yoki geympadning ID'sidan foydalanishni o'z ichiga oladi. Foydalanuvchi tajribasini hisobga oling va xaritalash mantig'ini aniq o'yinchi tayinlashlari bilan loyihalashtiring.
Kontroller Profillari va Moslashtirish
Eng keng auditoriyani qamrab olish va izchil tajribani ta'minlash uchun o'yinchilarga o'z kontroller xaritalarini moslashtirish imkoniyatini taklif qiling. Bu xususiyat ayniqsa qimmatlidir, chunki geympadlar tugma tartiblarida farqlanadi. O'yinchilarning afzalliklari ham bo'lishi mumkin, masalan, teskari yoki teskari bo'lmagan boshqaruvlar, va siz ularga tugma yoki o'q xaritasini o'zgartirish imkoniyatini berishingiz kerak. Boshqaruvlarni qayta xaritalash uchun o'yin ichidagi variantlarni taklif qilish o'yinning o'ynalishini sezilarli darajada oshiradi.
Amalga Oshirish Qadamlari:
- Foydalanuvchi Interfeysi: O'yiningizda o'yinchilarga har bir tugma va o'qning funksiyasini qayta tayinlash imkonini beradigan foydalanuvchi interfeysi elementini yarating. Bu sozlamalar menyusi yoki maxsus boshqaruv konfiguratsiyasi ekranini o'z ichiga olishi mumkin.
- Xaritalarni Saqlash: O'yinchilarga o'zlarining maxsus xaritalarini saqlashga ruxsat bering. Buni mahalliy saqlashda (
localStorage) yoki foydalanuvchi hisoblarida saqlash mumkin. - Kiritishni Qayta Ishlash: Kiritishni boshqarish mantig'ida o'yinchining maxsus xaritalarini qo'llang.
Bu yerda o'yinchi ma'lumotlarini qanday saqlash va yuklash mumkinligi haqida misol keltirilgan. Bu yuqorida tavsiflanganidek, kiritishni xaritalash tizimi qurilgan deb taxmin qiladi.
const DEFAULT_INPUT_MAPPINGS = { /* your default mappings */ };
let currentInputMappings = {};
function saveInputMappings() {
localStorage.setItem('gameInputMappings', JSON.stringify(currentInputMappings));
}
function loadInputMappings() {
const savedMappings = localStorage.getItem('gameInputMappings');
currentInputMappings = savedMappings ? JSON.parse(savedMappings) : DEFAULT_INPUT_MAPPINGS;
}
// Example of changing one specific mapping:
function changeButtonMapping(action, newButtonIndex) {
currentInputMappings[action].button = newButtonIndex;
saveInputMappings();
}
// Call loadInputMappings() at the beginning of your game.
loadInputMappings();
Ilg'or Texnikalar va Mulohazalar
Vibratsiya/Taktil Fikrbildirish
Gamepad API taktil fikrbildirishni qo'llab-quvvatlaydi, bu sizga kontrollerni titratish imkonini beradi. Barcha kontrollerlar bu xususiyatni qo'llab-quvvatlamaydi, shuning uchun qurilmani titratishga urinishdan oldin uning mavjudligini tekshirishingiz kerak. Shuningdek, o'yinchiga vibratsiyani o'chirib qo'yishga ruxsat berish muhim, chunki ba'zi o'yinchilar bu xususiyatni yoqtirmasligi mumkin.
function vibrateController(gamepad, duration, strength) {
if (!gamepad || !gamepad.vibrationActuator) return;
// Check the existence of vibration actuator (for compatibility)
if (typeof gamepad.vibrationActuator.playEffect === 'function') {
gamepad.vibrationActuator.playEffect('dual-rumble', {
duration: duration,
startDelay: 0,
strongMagnitude: strength,
weakMagnitude: strength
});
} else {
// Fallback for older browsers
gamepad.vibrationActuator.playEffect('rumble', {
duration: duration,
startDelay: 0,
magnitude: strength
});
}
}
Ushbu vibrateController() funksiyasi vibrationActuator mavjudligini tekshiradi va undan vibratsiya effektlarini ijro etish uchun foydalanadi.
Kontroller Batareyasi Holati
Gamepad API batareya darajasi haqidagi ma'lumotni to'g'ridan-to'g'ri ochib bermasa-da, ba'zi brauzerlar uni kengaytma API'lari yoki xususiyatlari orqali taqdim etishi mumkin. Bu qimmatli bo'lishi mumkin, chunki u sizga foydalanuvchiga kontrollerning batareya darajasi haqida fikr-mulohaza bildirish imkonini beradi, bu esa o'yin tajribasini yaxshilashi mumkin. Batareya holatini aniqlash usuli farq qilishi mumkinligi sababli, siz shartli tekshiruvlar yoki brauzerga xos yechimlardan foydalanishingiz kerak bo'ladi.
Brauzerlararo Moslik
Gamepad API barcha zamonaviy brauzerlar tomonidan qo'llab-quvvatlanadi. Biroq, turli brauzerlar o'rtasida xatti-harakatlarda yoki xususiyatlarni qo'llab-quvvatlashda nozik farqlar bo'lishi mumkin. Turli brauzerlar va platformalarda sinchkovlik bilan sinovdan o'tkazish izchil funksionallikni ta'minlash uchun juda muhimdir. Brauzer nomuvofiqliklarini oqilona hal qilish uchun xususiyatlarni aniqlashdan foydalaning.
Foydalanish Imkoniyati
Gamepad API'dan foydalanadigan o'yinlarni loyihalashda foydalanish imkoniyatini hisobga oling. Barcha o'yin elementlarini geympad yoki, agar kerak bo'lsa, klaviatura va sichqoncha yordamida boshqarish mumkinligiga ishonch hosil qiling. Turli o'yinchilarning ehtiyojlarini qondirish uchun boshqaruvlarni qayta xaritalash imkoniyatlarini taqdim eting va tugmalarni bosish va harakatlarni ko'rsatuvchi vizual yoki audio signallarni taqdim eting. O'yinchilar bazasini kengaytirish uchun har doim foydalanish imkoniyatini asosiy dizayn elementi qiling.
Gamepad API Integratsiyasi Uchun Eng Yaxshi Amaliyotlar
- Aniq Kiritish Dizayni: O'yiningizning boshqaruv sxemasini dasturlash jarayonining boshida rejalashtiring. O'yinchilar uchun o'rganish va eslab qolish oson bo'lgan intuitiv tartibni loyihalashtiring.
- Moslashuvchanlik: Kiritishni boshqarish kodingizni turli kontroller turlariga moslashuvchan va oson moslashtiriladigan qilib loyihalashtiring.
- Ishlash Samaradorligi: Ishlashdagi to'siqlarni oldini olish uchun kiritishni boshqarish kodingizni optimallashtiring. O'yin sikli ichida keraksiz hisob-kitoblar yoki operatsiyalardan saqlaning.
- Foydalanuvchi Fikr-mulohazasi: Tugmalar bosilganda yoki harakatlar bajarilganda o'yinchiga aniq vizual va audio fikr-mulohazalarni taqdim eting.
- Sinchkovlik Bilan Sinovdan O'tkazish: O'yiningizni keng turdagi kontrollerlar va brauzerlarda sinab ko'ring. Bu turli operatsion tizimlar va apparat konfiguratsiyalarida sinovdan o'tkazishni o'z ichiga oladi.
- Xatolarni Boshqarish: Geympadlar ulanmagan yoki uzilib qolgan holatlarni oqilona hal qilish uchun mustahkam xatolarni boshqarish tizimini joriy qiling. Foydalanuvchiga ma'lumot beruvchi xato xabarlarini taqdim eting.
- Hujjatlar: O'yiningizning boshqaruv sxemasi uchun aniq va qisqa hujjatlarni taqdim eting. Bu qaysi tugmalar va o'qlar qaysi harakatlarni bajarishi haqidagi ma'lumotlarni o'z ichiga olishi kerak.
- Jamiyat Qo'llab-quvvatlashi: Jamiyatingiz bilan muloqot qiling va geympad boshqaruvlari bo'yicha faol fikr-mulohazalarni izlang.
Misol: Geympad Qo'llab-quvvatlovchi Oddiy O'yin
Bu yerda o'yin siklining soddalashtirilgan versiyasi va ba'zi yordamchi kodlar keltirilgan. Ushbu misol yuqorida muhokama qilingan asosiy tushunchalarga, jumladan geympad ulanishi, tugma kiritishi va o'q kiritishiga qaratilgan va tushunarlilikni maksimal darajada oshirish uchun tuzilgan. Quyidagi kodda keltirilgan asosiy tushunchalarni o'z o'yin mantig'ingizni amalga oshirish uchun moslashtirishingiz mumkin.
// Game State
let playerX = 0;
let playerY = 0;
const PLAYER_SPEED = 5;
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// Input Mappings (as shown before)
const INPUT_MAPPINGS = {
// Example mappings
'A': { button: 0, action: 'jump' },
'leftStickX': { axis: 0, action: 'moveHorizontal' },
'leftStickY': { axis: 1, action: 'moveVertical' },
};
// Gamepad Data
let connectedGamepads = []; // Store connected gamepads
// --- Utility Functions ---
function updateGamepads() {
connectedGamepads = Array.from(navigator.getGamepads()).filter(gamepad => gamepad !== null);
console.log('Connected Gamepads:', connectedGamepads.map(g => g ? g.id : 'null'));
}
// --- Input Handling ---
function handleGamepadInput(gamepad) {
if (!gamepad) return;
const buttons = gamepad.buttons;
const axes = gamepad.axes;
// Button Input (simplified)
for (const mappingKey in INPUT_MAPPINGS) {
const mapping = INPUT_MAPPINGS[mappingKey];
if (mapping.button !== undefined && buttons[mapping.button].pressed) {
console.log(`Button ${mapping.action} pressed`);
// Perform action
if (mapping.action === 'jump') {
console.log('Jumping!');
}
}
}
// Axis Input
if (INPUT_MAPPINGS.leftStickX) {
const xAxis = axes[INPUT_MAPPINGS.leftStickX.axis];
if (Math.abs(xAxis) > 0.1) {
playerX += xAxis * PLAYER_SPEED;
}
}
if (INPUT_MAPPINGS.leftStickY) {
const yAxis = axes[INPUT_MAPPINGS.leftStickY.axis];
if (Math.abs(yAxis) > 0.1) {
playerY += yAxis * PLAYER_SPEED;
}
}
}
function updateInput() {
for (let i = 0; i < connectedGamepads.length; i++) {
handleGamepadInput(connectedGamepads[i]);
}
}
// --- Game Loop ---
function gameLoop() {
updateInput();
// Keep player within bounds
playerX = Math.max(0, Math.min(playerX, canvas.width));
playerY = Math.max(0, Math.min(playerY, canvas.height));
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw the player
ctx.fillStyle = 'blue';
ctx.fillRect(playerX, playerY, 20, 20);
requestAnimationFrame(gameLoop);
}
// --- Event Listeners ---
window.addEventListener('gamepadconnected', (event) => {
console.log('Gamepad connected:', event.gamepad.id);
updateGamepads();
});
window.addEventListener('gamepaddisconnected', (event) => {
console.log('Gamepad disconnected:', event.gamepad.id);
updateGamepads();
});
// --- Initialization ---
// Get a reference to the canvas element in your HTML
canvas.width = 600;
canvas.height = 400;
updateGamepads(); // Initial check
// Start the game loop after gamepad check
requestAnimationFrame(gameLoop);
Ushbu misol Gamepad API'ni o'yin sikli ichida ishlatishning asosiy tamoyillarini namoyish etadi. Kod o'yinni ishga tushiradi, hodisalarni tinglovchilar yordamida geympad ulanishlari va uzilishlarini boshqaradi va requestAnimationFrame yordamida asosiy o'yin siklini belgilaydi. Shuningdek, u o'yinchi pozitsiyasini boshqarish va oddiy o'yin elementini chizish uchun tugmalar va o'qlarni o'qishni ko'rsatadi. HTML-da "gameCanvas" id'siga ega canvas elementini qo'shishni unutmang.
Xulosa
Gamepad API veb-dasturchilarga brauzerda qiziqarli va jozibali o'yin tajribalarini yaratish imkoniyatini beradi. Uning asosiy tushunchalarini tushunib, eng yaxshi amaliyotlarni qo'llash orqali dasturchilar sezgir, platformalararo mos keluvchan va global auditoriya uchun yoqimli o'yinlar yaratishlari mumkin. Kontroller kiritishini aniqlash, o'qish va boshqarish qobiliyati keng imkoniyatlarni ochib beradi, bu esa veb-asosidagi o'yinlarni o'zlarining mahalliy hamkasblari kabi qiziqarli va qulay qiladi. Brauzerlar rivojlanishda davom etar ekan, Gamepad API yanada murakkablashishi mumkin, bu esa dasturchilarga geympad funksionalligi ustidan yanada ko'proq nazorat beradi. Ushbu maqolada tushuntirilgan usullarni birlashtirib, siz veb-ilovalaringizda geympadlarning kuchidan samarali foydalanishingiz mumkin.
Qiziqarli va qulay veb-o'yinlarni yaratish uchun Gamepad API kuchini qabul qiling! O'yinchilarning afzalliklarini hisobga olishni, moslashtirishni taklif qilishni va butun dunyo bo'ylab o'yinchilar uchun optimal o'yin tajribasini ta'minlash uchun sinchkovlik bilan sinovdan o'tkazishni unutmang.